home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / sv_ents.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-24  |  15.3 KB  |  628 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20.  
  21. #include "server.h"
  22.  
  23. /*
  24. =============================================================================
  25.  
  26. Encode a client frame onto the network channel
  27.  
  28. =============================================================================
  29. */
  30.  
  31.  
  32. /*
  33. =============
  34. SV_EmitPacketEntities
  35.  
  36. Writes a delta update of an entity_state_t list to the message.
  37. =============
  38. */
  39. void SV_EmitPacketEntities (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
  40. {
  41.     entity_state_t    *oldent, *newent;
  42.     int        oldindex, newindex;
  43.     int        oldnum, newnum;
  44.     int        from_num_entities;
  45.     int        bits;
  46.  
  47. #if 0
  48.     if (numprojs)
  49.         MSG_WriteByte (msg, svc_packetentities2);
  50.     else
  51. #endif
  52.         MSG_WriteByte (msg, svc_packetentities);
  53.  
  54.     if (!from)
  55.         from_num_entities = 0;
  56.     else
  57.         from_num_entities = from->num_entities;
  58.  
  59.     newindex = 0;
  60.     oldindex = 0;
  61.     while (newindex < to->num_entities || oldindex < from_num_entities)
  62.     {
  63.         if (newindex >= to->num_entities)
  64.             newnum = 9999;
  65.         else
  66.         {
  67.             newent = &svs.client_entities[(to->first_entity+newindex)%svs.num_client_entities];
  68.             newnum = newent->number;
  69.         }
  70.  
  71.         if (oldindex >= from_num_entities)
  72.             oldnum = 9999;
  73.         else
  74.         {
  75.             oldent = &svs.client_entities[(from->first_entity+oldindex)%svs.num_client_entities];
  76.             oldnum = oldent->number;
  77.         }
  78.  
  79.         if (newnum == oldnum)
  80.         {    // delta update from old position
  81.             // because the force parm is false, this will not result
  82.             // in any bytes being emited if the entity has not changed at all
  83.             // note that players are always 'newentities', this updates their oldorigin always
  84.             // and prevents warping
  85.             MSG_WriteDeltaEntity (oldent, newent, msg, false, newent->number <= maxclients->value);
  86.             oldindex++;
  87.             newindex++;
  88.             continue;
  89.         }
  90.  
  91.         if (newnum < oldnum)
  92.         {    // this is a new entity, send it from the baseline
  93.             MSG_WriteDeltaEntity (&sv.baselines[newnum], newent, msg, true, true);
  94.             newindex++;
  95.             continue;
  96.         }
  97.  
  98.         if (newnum > oldnum)
  99.         {    // the old entity isn't present in the new message
  100.             bits = U_REMOVE;
  101.             if (oldnum >= 256)
  102.                 bits |= U_NUMBER16 | U_MOREBITS1;
  103.  
  104.             MSG_WriteByte (msg,    bits&255 );
  105.             if (bits & 0x0000ff00)
  106.                 MSG_WriteByte (msg,    (bits>>8)&255 );
  107.  
  108.             if (bits & U_NUMBER16)
  109.                 MSG_WriteShort (msg, oldnum);
  110.             else
  111.                 MSG_WriteByte (msg, oldnum);
  112.  
  113.             oldindex++;
  114.             continue;
  115.         }
  116.     }
  117.  
  118.     MSG_WriteShort (msg, 0);    // end of packetentities
  119. }
  120.  
  121.  
  122.  
  123. /*
  124. =============
  125. SV_WritePlayerstateToClient
  126.  
  127. =============
  128. */
  129. void SV_WritePlayerstateToClient (client_frame_t *from, client_frame_t *to, sizebuf_t *msg)
  130. {
  131.     int                i;
  132.     int                pflags;
  133.     player_state_t    *ps, *ops;
  134.     player_state_t    dummy;
  135.     int                statbits;
  136.  
  137.     ps = &to->ps;
  138.     if (!from)
  139.     {
  140.         memset (&dummy, 0, sizeof(dummy));
  141.         ops = &dummy;
  142.     }
  143.     else
  144.         ops = &from->ps;
  145.  
  146.     //
  147.     // determine what needs to be sent
  148.     //
  149.     pflags = 0;
  150.  
  151.     if (ps->pmove.pm_type != ops->pmove.pm_type)
  152.         pflags |= PS_M_TYPE;
  153.  
  154.     if (ps->pmove.origin[0] != ops->pmove.origin[0]
  155.         || ps->pmove.origin[1] != ops->pmove.origin[1]
  156.         || ps->pmove.origin[2] != ops->pmove.origin[2] )
  157.         pflags |= PS_M_ORIGIN;
  158.  
  159.     if (ps->pmove.velocity[0] != ops->pmove.velocity[0]
  160.         || ps->pmove.velocity[1] != ops->pmove.velocity[1]
  161.         || ps->pmove.velocity[2] != ops->pmove.velocity[2] )
  162.         pflags |= PS_M_VELOCITY;
  163.  
  164.     if (ps->pmove.pm_time != ops->pmove.pm_time)
  165.         pflags |= PS_M_TIME;
  166.  
  167.     if (ps->pmove.pm_flags != ops->pmove.pm_flags)
  168.         pflags |= PS_M_FLAGS;
  169.  
  170.     if (ps->pmove.gravity != ops->pmove.gravity)
  171.         pflags |= PS_M_GRAVITY;
  172.  
  173.     if (ps->pmove.delta_angles[0] != ops->pmove.delta_angles[0]
  174.         || ps->pmove.delta_angles[1] != ops->pmove.delta_angles[1]
  175.         || ps->pmove.delta_angles[2] != ops->pmove.delta_angles[2] )
  176.         pflags |= PS_M_DELTA_ANGLES;
  177.  
  178.  
  179.     if (ps->viewoffset[0] != ops->viewoffset[0]
  180.         || ps->viewoffset[1] != ops->viewoffset[1]
  181.         || ps->viewoffset[2] != ops->viewoffset[2] )
  182.         pflags |= PS_VIEWOFFSET;
  183.  
  184.     if (ps->viewangles[0] != ops->viewangles[0]
  185.         || ps->viewangles[1] != ops->viewangles[1]
  186.         || ps->viewangles[2] != ops->viewangles[2] )
  187.         pflags |= PS_VIEWANGLES;
  188.  
  189.     if (ps->kick_angles[0] != ops->kick_angles[0]
  190.         || ps->kick_angles[1] != ops->kick_angles[1]
  191.         || ps->kick_angles[2] != ops->kick_angles[2] )
  192.         pflags |= PS_KICKANGLES;
  193.  
  194.     if (ps->blend[0] != ops->blend[0]
  195.         || ps->blend[1] != ops->blend[1]
  196.         || ps->blend[2] != ops->blend[2]
  197.         || ps->blend[3] != ops->blend[3] )
  198.         pflags |= PS_BLEND;
  199.  
  200.     if (ps->fov != ops->fov)
  201.         pflags |= PS_FOV;
  202.  
  203.     if (ps->rdflags != ops->rdflags)
  204.         pflags |= PS_RDFLAGS;
  205.  
  206.     if (ps->gunframe != ops->gunframe)
  207.         pflags |= PS_WEAPONFRAME;
  208.  
  209.     pflags |= PS_WEAPONINDEX;
  210.  
  211.     //
  212.     // write it
  213.     //
  214.     MSG_WriteByte (msg, svc_playerinfo);
  215.     MSG_WriteShort (msg, pflags);
  216.  
  217.     //
  218.     // write the pmove_state_t
  219.     //
  220.     if (pflags & PS_M_TYPE)
  221.         MSG_WriteByte (msg, ps->pmove.pm_type);
  222.  
  223.     if (pflags & PS_M_ORIGIN)
  224.     {
  225.         MSG_WriteShort (msg, ps->pmove.origin[0]);
  226.         MSG_WriteShort (msg, ps->pmove.origin[1]);
  227.         MSG_WriteShort (msg, ps->pmove.origin[2]);
  228.     }
  229.  
  230.     if (pflags & PS_M_VELOCITY)
  231.     {
  232.         MSG_WriteShort (msg, ps->pmove.velocity[0]);
  233.         MSG_WriteShort (msg, ps->pmove.velocity[1]);
  234.         MSG_WriteShort (msg, ps->pmove.velocity[2]);
  235.     }
  236.  
  237.     if (pflags & PS_M_TIME)
  238.         MSG_WriteByte (msg, ps->pmove.pm_time);
  239.  
  240.     if (pflags & PS_M_FLAGS)
  241.         MSG_WriteByte (msg, ps->pmove.pm_flags);
  242.  
  243.     if (pflags & PS_M_GRAVITY)
  244.         MSG_WriteShort (msg, ps->pmove.gravity);
  245.  
  246.     if (pflags & PS_M_DELTA_ANGLES)
  247.     {
  248.         MSG_WriteShort (msg, ps->pmove.delta_angles[0]);
  249.         MSG_WriteShort (msg, ps->pmove.delta_angles[1]);
  250.         MSG_WriteShort (msg, ps->pmove.delta_angles[2]);
  251.     }
  252.  
  253.     //
  254.     // write the rest of the player_state_t
  255.     //
  256.     if (pflags & PS_VIEWOFFSET)
  257.     {
  258.         MSG_WriteChar (msg, ps->viewoffset[0]*4);
  259.         MSG_WriteChar (msg, ps->viewoffset[1]*4);
  260.         MSG_WriteChar (msg, ps->viewoffset[2]*4);
  261.     }
  262.  
  263.     if (pflags & PS_VIEWANGLES)
  264.     {
  265.         MSG_WriteAngle16 (msg, ps->viewangles[0]);
  266.         MSG_WriteAngle16 (msg, ps->viewangles[1]);
  267.         MSG_WriteAngle16 (msg, ps->viewangles[2]);
  268.     }
  269.  
  270.     if (pflags & PS_KICKANGLES)
  271.     {
  272.         MSG_WriteChar (msg, ps->kick_angles[0]*4);
  273.         MSG_WriteChar (msg, ps->kick_angles[1]*4);
  274.         MSG_WriteChar (msg, ps->kick_angles[2]*4);
  275.     }
  276.  
  277.     if (pflags & PS_WEAPONINDEX)
  278.     {
  279.         MSG_WriteByte (msg, ps->gunindex);
  280.     }
  281.  
  282.     if (pflags & PS_WEAPONFRAME)
  283.     {
  284.         MSG_WriteByte (msg, ps->gunframe);
  285.         MSG_WriteChar (msg, ps->gunoffset[0]*4);
  286.         MSG_WriteChar (msg, ps->gunoffset[1]*4);
  287.         MSG_WriteChar (msg, ps->gunoffset[2]*4);
  288.         MSG_WriteChar (msg, ps->gunangles[0]*4);
  289.         MSG_WriteChar (msg, ps->gunangles[1]*4);
  290.         MSG_WriteChar (msg, ps->gunangles[2]*4);
  291.     }
  292.  
  293.     if (pflags & PS_BLEND)
  294.     {
  295.         MSG_WriteByte (msg, ps->blend[0]*255);
  296.         MSG_WriteByte (msg, ps->blend[1]*255);
  297.         MSG_WriteByte (msg, ps->blend[2]*255);
  298.         MSG_WriteByte (msg, ps->blend[3]*255);
  299.     }
  300.     if (pflags & PS_FOV)
  301.         MSG_WriteByte (msg, ps->fov);
  302.     if (pflags & PS_RDFLAGS)
  303.         MSG_WriteByte (msg, ps->rdflags);
  304.  
  305.     // send stats
  306.     statbits = 0;
  307.     for (i=0 ; i<MAX_STATS ; i++)
  308.         if (ps->stats[i] != ops->stats[i])
  309.             statbits |= 1<<i;
  310.     MSG_WriteLong (msg, statbits);
  311.     for (i=0 ; i<MAX_STATS ; i++)
  312.         if (statbits & (1<<i) )
  313.             MSG_WriteShort (msg, ps->stats[i]);
  314. }
  315.  
  316.  
  317. /*
  318. ==================
  319. SV_WriteFrameToClient
  320. ==================
  321. */
  322. void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg)
  323. {
  324.     client_frame_t        *frame, *oldframe;
  325.     int                    lastframe;
  326.  
  327. //Com_Printf ("%i -> %i\n", client->lastframe, sv.framenum);
  328.     // this is the frame we are creating
  329.     frame = &client->frames[sv.framenum & UPDATE_MASK];
  330.  
  331.     if (client->lastframe <= 0)
  332.     {    // client is asking for a retransmit
  333.         oldframe = NULL;
  334.         lastframe = -1;
  335.     }
  336.     else if (sv.framenum - client->lastframe >= (UPDATE_BACKUP - 3) )
  337.     {    // client hasn't gotten a good message through in a long time
  338. //        Com_Printf ("%s: Delta request from out-of-date packet.\n", client->name);
  339.         oldframe = NULL;
  340.         lastframe = -1;
  341.     }
  342.     else
  343.     {    // we have a valid message to delta from
  344.         oldframe = &client->frames[client->lastframe & UPDATE_MASK];
  345.         lastframe = client->lastframe;
  346.     }
  347.  
  348.     MSG_WriteByte (msg, svc_frame);
  349.     MSG_WriteLong (msg, sv.framenum);
  350.     MSG_WriteLong (msg, lastframe);    // what we are delta'ing from
  351.     MSG_WriteByte (msg, client->surpressCount);    // rate dropped packets
  352.     client->surpressCount = 0;
  353.  
  354.     // send over the areabits
  355.     MSG_WriteByte (msg, frame->areabytes);
  356.     SZ_Write (msg, frame->areabits, frame->areabytes);
  357.  
  358.     // delta encode the playerstate
  359.     SV_WritePlayerstateToClient (oldframe, frame, msg);
  360.  
  361.     // delta encode the entities
  362.     SV_EmitPacketEntities (oldframe, frame, msg);
  363. }
  364.  
  365.  
  366. /*
  367. =============================================================================
  368.  
  369. Build a client frame structure
  370.  
  371. =============================================================================
  372. */
  373.  
  374. byte        fatpvs[65536/8];    // 32767 is MAX_MAP_LEAFS
  375.  
  376. /*
  377. ============
  378. SV_FatPVS
  379.  
  380. The client will interpolate the view position,
  381. so we can't use a single PVS point
  382. ===========
  383. */
  384. void SV_FatPVS (vec3_t org)
  385. {
  386.     int        leafs[64];
  387.     int        i, j, count;
  388.     int        longs;
  389.     byte    *src;
  390.     vec3_t    mins, maxs;
  391.  
  392.     for (i=0 ; i<3 ; i++)
  393.     {
  394.         mins[i] = org[i] - 8;
  395.         maxs[i] = org[i] + 8;
  396.     }
  397.  
  398.     count = CM_BoxLeafnums (mins, maxs, leafs, 64, NULL);
  399.     if (count < 1)
  400.         Com_Error (ERR_FATAL, "SV_FatPVS: count < 1");
  401.     longs = (CM_NumClusters()+31)>>5;
  402.  
  403.     // convert leafs to clusters
  404.     for (i=0 ; i<count ; i++)
  405.         leafs[i] = CM_LeafCluster(leafs[i]);
  406.  
  407.     memcpy (fatpvs, CM_ClusterPVS(leafs[0]), longs<<2);
  408.     // or in all the other leaf bits
  409.     for (i=1 ; i<count ; i++)
  410.     {
  411.         for (j=0 ; j<i ; j++)
  412.             if (leafs[i] == leafs[j])
  413.                 break;
  414.         if (j != i)
  415.             continue;        // already have the cluster we want
  416.         src = CM_ClusterPVS(leafs[i]);
  417.         for (j=0 ; j<longs ; j++)
  418.             ((long *)fatpvs)[j] |= ((long *)src)[j];
  419.     }
  420. }
  421.  
  422.  
  423. /*
  424. =============
  425. SV_BuildClientFrame
  426.  
  427. Decides which entities are going to be visible to the client, and
  428. copies off the playerstat and areabits.
  429. =============
  430. */
  431. void SV_BuildClientFrame (client_t *client)
  432. {
  433.     int        e, i;
  434.     vec3_t    org;
  435.     edict_t    *ent;
  436.     edict_t    *clent;
  437.     client_frame_t    *frame;
  438.     entity_state_t    *state;
  439.     int        l;
  440.     int        clientarea, clientcluster;
  441.     int        leafnum;
  442.     int        c_fullsend;
  443.     byte    *clientphs;
  444.     byte    *bitvector;
  445.  
  446.     clent = client->edict;
  447.     if (!clent->client)
  448.         return;        // not in game yet
  449.  
  450.     // this is the frame we are creating
  451.     frame = &client->frames[sv.framenum & UPDATE_MASK];
  452.  
  453.     frame->senttime = svs.realtime; // save it for ping calc later
  454.  
  455.     // find the client's PVS
  456.     for (i=0 ; i<3 ; i++)
  457.         org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i];
  458.  
  459.     leafnum = CM_PointLeafnum (org);
  460.     clientarea = CM_LeafArea (leafnum);
  461.     clientcluster = CM_LeafCluster (leafnum);
  462.  
  463.     // calculate the visible areas
  464.     frame->areabytes = CM_WriteAreaBits (frame->areabits, clientarea);
  465.  
  466.     // grab the current player_state_t
  467.     frame->ps = clent->client->ps;
  468.  
  469.  
  470.     SV_FatPVS (org);
  471.     clientphs = CM_ClusterPHS (clientcluster);
  472.  
  473.     // build up the list of visible entities
  474.     frame->num_entities = 0;
  475.     frame->first_entity = svs.next_client_entities;
  476.  
  477.     c_fullsend = 0;
  478.  
  479.     for (e=1 ; e<ge->num_edicts ; e++)
  480.     {
  481.         ent = EDICT_NUM(e);
  482.  
  483.         // ignore ents without visible models
  484.         if (ent->svflags & SVF_NOCLIENT)
  485.             continue;
  486.  
  487.         // ignore ents without visible models unless they have an effect
  488.         if (!ent->s.modelindex && !ent->s.effects && !ent->s.sound
  489.             && !ent->s.event)
  490.             continue;
  491.  
  492.         // ignore if not touching a PV leaf
  493.         if (ent != clent)
  494.         {
  495.             // check area
  496.             if (!CM_AreasConnected (clientarea, ent->areanum))
  497.             {    // doors can legally straddle two areas, so
  498.                 // we may need to check another one
  499.                 if (!ent->areanum2
  500.                     || !CM_AreasConnected (clientarea, ent->areanum2))
  501.                     continue;        // blocked by a door
  502.             }
  503.  
  504.             // beams just check one point for PHS
  505.             if (ent->s.renderfx & RF_BEAM)
  506.             {
  507.                 l = ent->clusternums[0];
  508.                 if ( !(clientphs[l >> 3] & (1 << (l&7) )) )
  509.                     continue;
  510.             }
  511.             else
  512.             {
  513.                 // FIXME: if an ent has a model and a sound, but isn't
  514.                 // in the PVS, only the PHS, clear the model
  515.                 if (ent->s.sound)
  516.                 {
  517.                     bitvector = fatpvs;    //clientphs;
  518.                 }
  519.                 else
  520.                     bitvector = fatpvs;
  521.  
  522.                 if (ent->num_clusters == -1)
  523.                 {    // too many leafs for individual check, go by headnode
  524.                     if (!CM_HeadnodeVisible (ent->headnode, bitvector))
  525.                         continue;
  526.                     c_fullsend++;
  527.                 }
  528.                 else
  529.                 {    // check individual leafs
  530.                     for (i=0 ; i < ent->num_clusters ; i++)
  531.                     {
  532.                         l = ent->clusternums[i];
  533.                         if (bitvector[l >> 3] & (1 << (l&7) ))
  534.                             break;
  535.                     }
  536.                     if (i == ent->num_clusters)
  537.                         continue;        // not visible
  538.                 }
  539.  
  540.                 if (!ent->s.modelindex)
  541.                 {    // don't send sounds if they will be attenuated away
  542.                     vec3_t    delta;
  543.                     float    len;
  544.  
  545.                     VectorSubtract (org, ent->s.origin, delta);
  546.                     len = VectorLength (delta);
  547.                     if (len > 400)
  548.                         continue;
  549.                 }
  550.             }
  551.         }
  552.  
  553.         // add it to the circular client_entities array
  554.         state = &svs.client_entities[svs.next_client_entities%svs.num_client_entities];
  555.         if (ent->s.number != e)
  556.         {
  557.             Com_DPrintf ("FIXING ENT->S.NUMBER!!!\n");
  558.             ent->s.number = e;
  559.         }
  560.         *state = ent->s;
  561.  
  562.         // don't mark players missiles as solid
  563.         if (ent->owner == client->edict)
  564.             state->solid = 0;
  565.  
  566.         svs.next_client_entities++;
  567.         frame->num_entities++;
  568.     }
  569. }
  570.  
  571.  
  572. /*
  573. ==================
  574. SV_RecordDemoMessage
  575.  
  576. Save everything in the world out without deltas.
  577. Used for recording footage for merged or assembled demos
  578. ==================
  579. */
  580. void SV_RecordDemoMessage (void)
  581. {
  582.     int            e;
  583.     edict_t        *ent;
  584.     entity_state_t    nostate;
  585.     sizebuf_t    buf;
  586.     byte        buf_data[32768];
  587.     int            len;
  588.  
  589.     if (!svs.demofile)
  590.         return;
  591.  
  592.     memset (&nostate, 0, sizeof(nostate));
  593.     SZ_Init (&buf, buf_data, sizeof(buf_data));
  594.  
  595.     // write a frame message that doesn't contain a player_state_t
  596.     MSG_WriteByte (&buf, svc_frame);
  597.     MSG_WriteLong (&buf, sv.framenum);
  598.  
  599.     MSG_WriteByte (&buf, svc_packetentities);
  600.  
  601.     e = 1;
  602.     ent = EDICT_NUM(e);
  603.     while (e < ge->num_edicts) 
  604.     {
  605.         // ignore ents without visible models unless they have an effect
  606.         if (ent->inuse &&
  607.             ent->s.number && 
  608.             (ent->s.modelindex || ent->s.effects || ent->s.sound || ent->s.event) && 
  609.             !(ent->svflags & SVF_NOCLIENT))
  610.             MSG_WriteDeltaEntity (&nostate, &ent->s, &buf, false, true);
  611.  
  612.         e++;
  613.         ent = EDICT_NUM(e);
  614.     }
  615.  
  616.     MSG_WriteShort (&buf, 0);        // end of packetentities
  617.  
  618.     // now add the accumulated multicast information
  619.     SZ_Write (&buf, svs.demo_multicast.data, svs.demo_multicast.cursize);
  620.     SZ_Clear (&svs.demo_multicast);
  621.  
  622.     // now write the entire message to the file, prefixed by the length
  623.     len = LittleLong (buf.cursize);
  624.     fwrite (&len, 4, 1, svs.demofile);
  625.     fwrite (buf.data, buf.cursize, 1, svs.demofile);
  626. }
  627.  
  628.